/*
Data 1701/11
Projeto  : AURE ( Automação Residencial )
Autores  : André Machado e Gabriel Teodoro
Ano : 2011
CIMOL Curso Técnico de eletrônica
Compilador : SDCC
usuario root tem todos privilegios e nao precisa de senha
usuario comum precisa de senha
senha padrao = 1,2,3,4
*/
/*********************************************************************
TH1 values for different baud rates

baud rate   clock     SMOD   TH1   Error
9600     12.000MHZ   1    0xF9  7%
4800     12.000MHZ   0    0xF9  7%
2400     12.000MHZ   0    0xF3  0.16%
1200     12.000MHZ   0    0xE6  0.16%
9600     11.059MHz   0    0xFD  0
4800     11.059MHz   0    0xFA  0
2400     11.059MHz   0    0xF4  0
1200     11.059MHz   0    0xE8  0

Um exemplo que mostra como inicializar a porta serial em 2400 baud

void serial_init(void)
{
 SCON = 0x50;   //setup for 8bit data
 TMOD = 0x20;  //setup timer 1 for auto-reload
 TH1 = 0xF3;   //setup for 2400 baud
 TR1 = 1;    //turn on timer 1
 TL = 1;     //indicate ready to transmit
}


***********************************************************************/

/*********SAIDA DO HT DECODER DTMF*************************************
tecla   D3 D2 D1 D0     decimal
1       0001            1
2       0010            2
3       0011            3
4       0100            4
5       0101            5
6       0110            6
7       0111            7
8       1000            8
9       1001            9
0       1010            10
*       1011            11
#       1100            12
***********************************************************************/

#include <at89x52.h>

//=======================================================================

#define RING P1_6
#define DV_DTMF P1_4
#define BATE_RELE P1_5
#define VT_RF P0_4


//=======================================================================
bit recepcao_ser = 0;
unsigned char NUMERO = 0;
unsigned char DIGITO = 0;
unsigned char CMD_SERIAL = 0;
unsigned char tentativas = 0;
unsigned char tempo_1s = 0;
unsigned char tempo_10s = 0;
unsigned char index = 0;
unsigned char buffer[] = {0,0,0,0};

//=======================================================================

void delay_ms(unsigned int x)
{
    unsigned int i,j;
        for(j=0; j<=x; j++)
        {
            for(i=0; i<=100; i++)
            {
            ;
            }
        }
}

//=======================================================================

void send_string(unsigned char *s)
{
    while(*s != 0x0)
    {
        SBUF = *s;
        while(!TI);
        TI = 0;
        s++;
    }
}

//=======================================================================

void send_char(unsigned char ch)
{
    SBUF = ch;
    while(!TI);
    TI = 0;
}

//=======================================================================


void tom_confirmacao(void)
{
    //por fazer
    //falta circuito fidback
    //que estará disponivel na versao 1.6
}


//=======================================================================

void TASK_1(void)
{
 if(RING)
 {
        delay_ms(10);
        if(RING)
        {
            BATE_RELE = 1;
            send_string("\r\nChamada Atendida\r\n");
            TR0 = 1; //incia o timer0 logo que atende a chamada
        }
 }
}

//=======================================================================

void TASK_2(void)
{

 if(DV_DTMF)
 {
  NUMERO = P1 & 0xF;     /*pega o bina*/
  while(DV_DTMF);       /*trava ate soltar a tecla*/
  TR0 = 0;                    /*para o timer*/
  buffer[index] = NUMERO;   /*coloca no buffer o bina*/
  index++;           /*incrementa indice do array*/

        /*
        parar o timer com o bina funcionou
        mas reinicia-lo ao soltar a tecla nao rever, este item
        */

 }

 switch(NUMERO)
 {
            case 1:
                send_char(49); //envia o char correspondente ascii 1
                NUMERO = 0;
                break;
            case 2:
                send_char(50); //envia o char correspondente ascii 2
                NUMERO = 0;
                break;
            case 3:
                send_char(51); //envia o char correspondente ascii 3
                NUMERO = 0;
				break;
            case 4:
				send_char(52); //envia o char correspondente ascii 4
                NUMERO = 0;
                break;
            case 5:
                send_char(53); //envia o char correspondente ascii 5
                NUMERO = 0;
                break;
            case 6:
                send_char(54); //envia o char correspondente ascii 6
                NUMERO = 0;
                break;
            case 7:
                send_char(55); //envia o char correspondente ascii 7
                NUMERO = 0;
                break;
            case 8:
                send_char(56); //envia o char correspondente ascii 8
                NUMERO = 0;
                break;
            case 9:
                send_char(57); //envia o char correspondente ascii 9
                NUMERO = 0;
                break;
            case 10:
                send_char(48); //envia o char correspondente ascii 0
                NUMERO = 0;
                BATE_RELE = 1;
				break;
            case 11:
                send_char(42); //envia o char correspondente ascii *
                TR0 = 1;
                NUMERO = 0;
                index = 0;
				tentativas++;
                send_string("\r\nReset senha\r\n");
                break;
            case 12:
                send_char(35); //envia o char correspondente ascii #
                break;
        }
}

//=======================================================================

void TASK_3(void)
{

    if( index > 3 )
    {
         index = 0;

            if( (buffer[0] == 1) && (buffer[1] == 2) && (buffer[2] == 3) && (buffer[3] == 4) )
            {
                NUMERO = 12;
                //tom_confirmacao();
                send_string("\r\nAcesso Permitido\r\n");
            }
			else
                {
                    //tom_confirmacao();
                    //delay_ms(10);
                    //tom_confirmacao();
                    send_string("\r\nSenha Errada\r\n");
                    tentativas++;
                }
    }
}

//=======================================================================

void limpa_buffer()
{
    unsigned char x;
    for( x = 0; x <= 3; x++ )
    {
        buffer[x] = 0;
    }

}

//=======================================================================


void TASK_4(void)
{

	if(VT_RF)
	{
		DIGITO = P0 & 0xF;
		while(VT_RF);
	}

		switch(DIGITO)
		{
            case 1:
                send_char(49); //envia o char correspondente ascii 1
                DIGITO = 0;
				P2 = 173;
                break;
            case 2:
                send_char(50); //envia o char correspondente ascii 2
                DIGITO = 0;
                P2 = 194;
				break;
            case 3:
                send_char(51); //envia o char correspondente ascii 3
                DIGITO = 0;
                P2 = 188;
				break;
            case 4:
				send_char(52); //envia o char correspondente ascii 4
                DIGITO = 0;
                P2 = 205;
				break;
            case 5:
                send_char(53); //envia o char correspondente ascii 5
                DIGITO = 0;
                P2 = 214;
				break;
            case 6:
                send_char(54); //envia o char correspondente ascii 6
                DIGITO = 0;
                P2 = 223;
				break;
            case 7:
                send_char(55); //envia o char correspondente ascii 7
                DIGITO = 0;
                P2 = 231;
				break;
            case 8:
                send_char(56); //envia o char correspondente ascii 8
                DIGITO = 0;
                P2 = 239;
				break;
            case 9:
                send_char(57); //envia o char correspondente ascii 9
                DIGITO = 0;
                P2 = 247;
				break;
            case 10:
                send_char(48); //envia o char correspondente ascii 0
                DIGITO = 0;
                P2 = 255;
				break;
            case 11:
                send_char(42); //envia o char correspondente ascii *
                DIGITO = 0;
				P0_5 = ~P0_5;
                //P2 = ;
				break;
            case 12:
                send_char(35); //envia o char correspondente ascii #
				DIGITO = 0;
                //P2 = ;
				break;
    }

 }

//=======================================================================

void TASK_5(void)
{
    if(recepcao_ser)
    {
         switch(CMD_SERIAL)
         {
            case 49:
                send_char(49); //envia o char correspondente ascii 1
                CMD_SERIAL = 0;
                P2 = 173;
                //tom_confirmacao();
                break;
            case 50:
                send_char(50); //envia o char correspondente ascii 2
                CMD_SERIAL = 0;
                P2 = 194;
                break;
            case 51:
                send_char(51); //envia o char correspondente ascii 3
                CMD_SERIAL = 0;
                P2 = 188;
                break;
            case 52:
                send_char(52); //envia o char correspondente ascii 4
                CMD_SERIAL = 0;
                P2 = 205;
                break;
            case 53:
                send_char(53); //envia o char correspondente ascii 5
                CMD_SERIAL = 0;
                P2 = 214;
                break;
            case 54:
                send_char(54); //envia o char correspondente ascii 6
                CMD_SERIAL = 0;
                P2 = 223;
                break;
            case 55:
                send_char(55); //envia o char correspondente ascii 7
                CMD_SERIAL = 0;
                P2 = 231;
                break;
            case 56:
                send_char(56); //envia o char correspondente ascii 8
                CMD_SERIAL = 0;
                P2 = 239;
                break;
            case 57:
                send_char(57); //envia o char correspondente ascii 9
                CMD_SERIAL = 0;
                P2 = 247;
                break;
            case 48:
                send_char(48); //envia o char correspondente ascii 0
                CMD_SERIAL = 0;
                P2 = 255;
                break;
        }
    }
}


//=======================================================================

void ISR_timer0() interrupt 1
{

 TH0 = 0x4B;
 TL0 = 0xFF;
 tempo_1s++;  /*incrementado a cada 50ms*/

}

//=======================================================================


void ISR_SERIAL() interrupt 4
{

    if(RI)        /*sinaliza que chegou dado*/
    {
        RI = 0;       /*reset para nova recepção*/
        CMD_SERIAL = SBUF;
        TR0 = 0;            /*stop timer0*/
        //BATE_RELE = 0;
        recepcao_ser = 1;
    }
}


//=======================================================================

void main(void)
{
EA = 1;         /*enabled all interrupts*/
ET0 = 1;        /*enabled interrupt timer0*/
ES = 1;         /*enabled interrupt serial*/
PS = 1;         /*enabled priority interrupt serial*/
SCON = 0x50;
TMOD = 0x21;
TH0 = 0x4B;
TL0 = 0xFF;
TR0 = 0;  		/*timer0 stop*/
TH1 = 0xF3;  	/*setup baud rate 2400*/
//TR1 = 1;  		/*timer1 run*/
TI = 1;   		/*enabled para receber dados*/
BATE_RELE = 0; 	/*enabled for receiver ring*/
RING = 0;
P2 = 0x00;

//=======================================================================

delay_ms(100);
TR1 = 1;
send_string("\r\nIniciando Sistema\r\n");
while(1)
{

//=======================================================================

while(NUMERO != 12)
{
	TASK_1(); //RING
	TASK_2(); //DV_DTMF
	TASK_3(); //Senha
	TASK_4(); //RF
    TASK_5(); //SERIAL

	if(tempo_1s == 20) //se entrar aqui passou-se 1seg
	{
		tempo_1s = 0;
		tempo_10s++;
		send_char(42);

			if(tempo_10s == 10)  //se entrar aqui passou-se 10seg
			{
				BATE_RELE = 0;
				tempo_10s = 0;
				send_string("\r\nChamada encerrada\r\n");
				send_string("\r\nTempo Limite Atingido\r\n");
				TR0 = 0;
			}
	}


	if(tentativas == 3)
	{
		BATE_RELE = 0;
		tentativas = 0;
		send_string("\r\nNumero de tentativas excedido\r\n");
	}
}

//=======================================================================


NUMERO = 0;
limpa_buffer();


//=======================================================================

while(NUMERO != 12)  /*se entrou aqui o usuario é root*/
{
	TASK_4();   //RF
    TASK_5();   //SERIAL

    if(DV_DTMF)
    {
        NUMERO = P1 & 0xF;    /*pega o bina*/
        while(DV_DTMF);      /*trava ate soltar a tecla*/
    }

        switch(NUMERO)
        {
            case 1:
                send_char(49); //envia o char correspondente ascii 1
                NUMERO = 0;
				P2 = 173;
                break;
            case 2:
                send_char(50); //envia o char correspondente ascii 2
                NUMERO = 0;
				P2 = 194;
                break;
            case 3:
                send_char(51); //envia o char correspondente ascii 3
                NUMERO = 0;
                P2 = 188;
				break;
            case 4:
				send_char(52); //envia o char correspondente ascii 4
                NUMERO = 0;
                P2 = 205;
				break;
            case 5:
                send_char(53); //envia o char correspondente ascii 5
                NUMERO = 0;
                P2 = 214;
				break;
            case 6:
                send_char(54); //envia o char correspondente ascii 6
                NUMERO = 0;
                P2 = 223;
				break;
            case 7:
                send_char(55); //envia o char correspondente ascii 7
                NUMERO = 0;
                P2 = 231;
				break;
            case 8:
                send_char(56); //envia o char correspondente ascii 8
                NUMERO = 0;
                P2 = 239;
				break;
            case 9:
                send_char(57); //envia o char correspondente ascii 9
                NUMERO = 0;
                P2 = 247;
				break;
            case 10:
                send_char(48); //envia o char correspondente ascii 0
                NUMERO = 0;
                P2 = 255;
				break;
            case 11:
                send_char(42); //envia o char correspondente ascii *
                NUMERO = 0;
                P0_5 = ~P0_5;
                //P2 = ;
				break;
            case 12:
                //este derruba a ligação
				//BATE_RELE = 0;
                send_char(35); //envia o char correspondente ascii #
                //P2 = ;
				break;
        }

}

NUMERO = 0;
DIGITO = 0;
BATE_RELE = 0;
send_string("\r\nTelecomandos Enviados\r\n");
//=======================================================================

}//end loop forever
}//end main
